package jianli;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/photodownload")
@MultipartConfig
public class photodownload extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public photodownload() {
        super();
        // TODO Auto-generated constructor stub
    }
    /**
     * 文件下载
     * 		思路:读服务器文件，写到浏览器（客户端）
     * 		步骤:
     * 			1. 通过文件名，获取文件真实路径。
     * 			2. 创建FileInputStream输入流，读入文件。
     * 			3. 创建输出流（response），响应给浏览器(注意文件名乱码的处理)，实现文件下载功能。
     */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//以下两行解决请求与响应中文乱码问题
		request.setCharacterEncoding("UTF-8");//POST
		response.setContentType("text/html;charset=UTF-8");//一石三鸟
//		PrintWriter out = response.getWriter();
		//取文件上传servlet中超链接中的Get请求参数中的file值，即文件名
		try {
			//1.通过文件名，获取文件真实路径。
			String fname = request.getParameter("file");
			System.out.println("photodownload.java中看一下取的下载超链接中的文件名："+fname);
			String realPath = getServletContext().getRealPath("/photo/"+fname);
			System.out.println("photodownload.java中看一下上传的照片在服务器中全路径:"+realPath);
			//2. 创建FileInputStream输入流，读入文件。
			FileInputStream fis = new FileInputStream(realPath);
			//3.创建输出流（response），响应给浏览器，实现文件下载功能。
			ServletOutputStream ops = response.getOutputStream();
			//在servlet规范中指出，response.getOutputStream()和response.getWriter()方法会产生冲突，一个是二进制流，一个是文本字符流，不能同时存在，无论先调用哪一个，在调用第二个时候应会抛出 IllegalStateException；
			//必须设置两个响应头，设置Content-Disposition：它的默认值为inline，表示在浏览器窗口中打开！设置浏览器响应体内容格式为附件格式。(告诉浏览器，文件为附件，别打开，下载。)
			//attachment;filename=xxx要不然我们输出的内容不会弹出保存框，只会显示在浏览器中。		
			//设置Content-Type：你传递给客户端的文件是什么MIME类型然后我们就可以new一个输入流来读取本地硬盘中的文件，在输出到ServleoutputStream中再来一行代码流过：
			String mimeType = request.getServletContext().getMimeType(fname);
			response.setContentType(mimeType);
			//解决文件名中文乱码问题
			//针对不同的浏览器使用不同的编码方式 火狐浏览器使用的是Base64编码，其他浏览器一般都是使用url编码
			//解决下载文件中文乱码问题，当中文文字超过17个时，IE6 无法下载文件。这是IE的bug，参见微软的知识库文章 KB816868 。
			//原因可能是IE在处理 Response Header 的时候，对header的长度限制在150字节左右。而一个汉字编码成UTF-8是9个字节，
			//那么17个字便是153个字节，所以会报错。而且不跟后缀也 不对
			String header = request.getHeader("User-Agent");
			String utf8filename;
//			if(header != null && header.contains("Firefox")) {//火狐浏览器
//			utf8filename = "=?utf-8?B?"+new BASE64Encoder().encode(fname.getBytes("utf-8"))+"?=";
//			}else {//其它浏览器
				utf8filename = URLEncoder.encode(fname, "UTF-8");
//			}
			System.out.println("photodownload.java中看一下经UTF8编码的下载文件名："+utf8filename);
			//设置浏览器响应体内容格式，为附件格式。(告诉浏览器，文件为附件，别打开，下载。)
			response.setHeader("Content-Disposition", "attachment; filename="+utf8filename);
//			//边读边写
			byte[] in = new byte[2048];
			while (fis.read(in, 0, in.length) != -1) {
				ops.write(in);
			}
			ops.flush();
			ops.close();
			fis.close();
		}catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}
